#ifndef __TOKEN_H
#define __TOKEN_H 1

#include <string>

enum TokenType : int {
  kTokenEof = 0,
  kTokenAuto,
  kTokenRegister,
  kTokenFunc,
  kTokenVar,
  kTokenVoid,
  kTokenBool,
  kTokenChar,
  kTokenShort,
  kTokenInt,
  kTokenLong,
  kTokenDouble,
  kTokenFloat,
  kTokenSigned,
  kTokenUnsigned,
  kTokenTrue,
  kTokenFalse,
  kTokenEnum,
  kTokenStruct,
  kTokenUnion,
  kTokenExtern,
  kTokenStatic,
  kTokenConst,
  kTokenSizeof,
  kTokenTypedef,
  kTokenFor,
  kTokenDo,
  kTokenWhile,
  kTokenBreak,
  kTokenContinue,
  kTokenIf,
  kTokenElse,
  kTokenSwitch,
  kTokenCase,
  kTokenDefault,
  kTokenReturn,
  kTokenGoto,
  kTokenVolatile,

  kTokenQuestion,     // ?
  kTokenSemi,         // ;
  kTokenOpComma,        // ,
  kTokenDot,          // .
  kTokenColon,        // :
  kTokenCont,         //
  kTokenLeftParen,       // (
  kTokenRightParen,       // )
  kTokenLeftBrack,       // [
  kTokenRightBrack,       // ]
  kTokenLeftCurly,       // {
  kTokenRightCurly,       // }

  kTokenPlus,           // +
  kTokenMinus,         // -
  kTokenStar,          // *
  kTokenOpDiv,           // /
  kTokenOpReminder,           // %
  kTokenSelfInc,           // ++
  kTokenSelfDec,           // --

  kTokenOpGreat,            // >
  kTokenOpLess,            // <
  kTokenOpEqual,            // ==
  kTokenOpGreatEq,            // >=
  kTokenOpLessEq,            // <=
  kTokenOpNotEq,            // !=

  kTokenOpLogicAnd,           // &&
  kTokenOpLogicOr,            // ||
  kTokenOpLogicNot,           // !

  kTokenAmp,          // &

  kTokenOpBitOr,           // |
  kTokenOpBitNot,          // ~
  kTokenOpBitXor,          // ^
  kTokenOpShiftLeft,           // <<
  kTokenOpShiftRight,           // >>

  kTokenOpAssign,        // =

  kTokenOpAddAssign,    // +=
  kTokenOpSubAssign,  // -=
  kTokenOpMultAssign,   // *=
  kTokenOpDivAssign,    // /=
  kTokenOpModAssign,    // %=

  kTokenOpBitAndAssign,   // &=
  kTokenOpBitOrAssign,    // |=
  kTokenOpBitXorAssign,   // ^=
  kTokenOpShiftLeftAssign,    // <<=
  kTokenOpShiftRightAssign,    // >>=


  kTokenMemberAccess,           // .
  kTokenOpPointer,           // ->

  kTokenPreprocess,       //#

  kTokenIdentifier,

  kTokenLiteralChar,
  kTokenLiteraltInteger,
  kTokenLiteralFloat,
  kTokenLiteralString,
};


struct Token {
  int line = 0;
  TokenType kind = kTokenEof;
  std::string name;
};


#endif //__TOKEN_H